/*
 * Created on 07.12.2003
 */
package vitalsFacade;

import observations.*;
import java.util.*;

/**
 <code>VitalsFacade</code> Facade from the application facade pattern.
 
 @author Sascha Hemminger
 @version 2004-09-10
 */
public class VitalsFacade {

  private Hashtable attributes = new Hashtable();

  private Date date;

  private Patient subject;

  /**
   * Sole constructor for the application facade.
   
   @param subject
   *            the patient you are dealing with at the moment
   */
  public VitalsFacade(Patient subject) {
    this.subject = subject;
    date = new Date();
    setupAttributes();
  }

  private MeasurementAttribute bloodPressureDiastolicAttribute() {
    return (MeasurementAttributeattributes.get("BloodPressureDiastolic");
  }

  private MeasurementAttribute bloodPressureSystolicAttribute() {
    return (MeasurementAttributeattributes.get("BloodPressureSystolic");
  }

  private BMIAttribute bmiAttribute() {
    BMIAttribute bmiAttribute = (BMIAttributeattributes.get("BMI");
    bmiAttribute.calculate(getHeight(), getWeight());
    now();
    bmiAttribute.save();
    return bmiAttribute;
  }

  private MeasurementAttribute breathingRateAttribute() {
    return (MeasurementAttributeattributes.get("BreathingRate");
  }

  private GenderAttribute genderAttribute() {
    return (GenderAttributeattributes.get("Gender");
  }

  /**
   * Searches the value for the diastolic blood pressure attribute and gives a
   * string representing the value.
   
   @return the diastolic blood pressure in mm/Hg if saved else empty string
   @see #setBloodPressureDiastolic
   */
  public String getBloodPressureDiastolic() {
    String result = bloodPressureDiastolicAttribute().value();
    return (result == nullnew String("": result;
  }

  /**
   * Searches the phenomenon that describes the quality of the diastolic blood
   * pressure (eg. 'high').
   
   @return a valuation in quality for the diastolic blood pressure if
   *         diastolic blood pressure is saved else empty string
   */
  public String getBloodPressureDiastolicName() {
    String result = bloodPressureDiastolicAttribute().name();
    return (result == nullnew String("": result;
  }

  /**
   * Searches the latest value of the systolic blood pressure and gives a
   * string representing it.
   
   @return the systolic blood pressure in mm/Hg if saved else empty string
   @see #setBloodPressureSystolic(String)
   */
  public String getBloodPressureSystolic() {
    String result = bloodPressureSystolicAttribute().value();
    return (result == nullnew String("": result;
  }

  /**
   * Searches the phenomenon that describes the quality of the diastolic blood
   * pressure (eg. 'high').
   
   @return a valuation in quality for the systolic blood pressure if
   *         systolic blood pressure is saved else empty string
   */
  public String getBloodPressureSystolicName() {
    String result = bloodPressureSystolicAttribute().name();
    return (result == nullnew String("": result;
  }

  /**
   * Gives the calculated body mass index of the patient.
   
   @return body mass index of the patient if saved else empty string
   */
  public String getBMI() {
    String result = bmiAttribute().value();
    return (result == nullnew String("": result;
  }

  /**
   * Gives a valuation in quality for the BMI (eg. 'obese') if all necessary
   * data (height, weight and gender) exists.
   
   @return a valuation in quality for the calculated body mass index
   */
  public String getBMIName() {
    String result = bmiAttribute().name();
    return (result == nullnew String("": result;
  }

  /**
   * Searches the latest value for a patient's breathing rate and gives a
   * string representation.
   
   @return latest breathing in breaths/min rate if saved else empty string
   @see #setBreathingRate(String)
   */
  public String getBreathingRate() {
    String result = breathingRateAttribute().value();
    return (result == nullnew String("": result;
  }

  /**
   * Gives a valuation in quality for the breathing rate (eg. 'normal').
   
   @return a valuation in quality for the actual breathing rate if breathing
   *         rate is saved else empty string
   */
  public String getBreathingRateName() {
    String result = breathingRateAttribute().name();
    return (result == nullnew String("": result;
  }

  /**
   * Used to decide whether a measurement is the latest or not.
   
   @return actual date
   */
  public Date getDate() {
    return date;
  }

  /**
   * Should be self-explanatory!
   
   @return a patient's gender (male or female ;))
   @see #setGender(String)
   */
  public String getGender() {
    String result = genderAttribute().value();
    return (result == nullnew String("": result;
  }

  /**
   * Searches the latest value of a patient's heart rate and gives a string
   * representation.
   
   @return latest heart rate in beats/min if saved else empty string
   @see #setHeartRate(String)
   */
  public String getHeartRate() {
    String result = heartRateAttribute().value();
    return (result == nullnew String("": result;
  }

  /**
   * Gives a valuation in quality for the heart rate (eg. 'fast).
   
   @return a valuation in quality for the actual heart rate if heart rate is
   *         saved else empty string
   */
  public String getHeartRateName() {
    String result = heartRateAttribute().name();
    return (result == nullnew String("": result;
  }

  /**
   * Gives patient's heigth in inches.
   
   @return the patient's height in inches if saved else empty string
   @see #setHeight(String)
   */
  public String getHeight() {
    String result = heightAttribute().value();
    return (result == nullnew String("": result;
  }

  /**
   * Gives a patient's level of consciousness (eg. 'aware').
   
   @return a patient's level of consciousness
   @see #setLevelOfConsciousness(String)
   */
  public String getLevelOfConsciousness() {
    return levelOfConsciousnessAttribute().value();
  }

  /**
   * Use this if you want to get to know all possible values of LOC.
   
   @return a list of all legal levels of consciousness (most likely aware,
   *         verbal, pain and unresponsive);
   */
  public Enumeration getLevelOfConsciousnessValues() {
    return levelOfConsciousnessAttribute().legalValues();
  }

  /**
   * Gives the patient's name.
   
   @return the patient's name
   */
  public String getName() {
    return subject.getName();
  }

  /**
   * Lets you see if patient is in shock.
   
   @return true if patient is in shock else false
   @see #setShock(boolean)
   */
  public boolean getShock() {
    return shockAttribute().value();
  }

  /**
   * Gets the actual patient object.
   
   @return patient loaded at the moment
   @see #setSubject(String)
   */
  public Patient getSubject() {
    return subject;
  }

  /**
   * Gives a patient's weight.
   
   @return weight of the patient measured in pounds if saved else empty
   *         string
   @see #setWeight(String)
   */
  public String getWeight() {
    String result = weightAttribute().value();
    return (result == nullnew String("": result;
  }

  private MeasurementAttribute heartRateAttribute() {
    return (MeasurementAttributeattributes.get("HeartRate");
  }

  private MeasurementAttribute heightAttribute() {
    return (MeasurementAttributeattributes.get("Height");
  }

  private LocAttribute levelOfConsciousnessAttribute() {
    return (LocAttributeattributes.get("LevelOfConsciousness");
  }

  /**
   * Loads all attributes related to the patient.
   */
  public void loadAttributes() {
    GenderAttribute genderRetrieve = (GenderAttributeattributes
        .get("Gender");
    genderRetrieve.load();
    LocAttribute locRetrieve = (LocAttributeattributes
        .get("LevelOfConsciousness");
    locRetrieve.load();
    MeasurementAttribute breathRateRetrieve = (MeasurementAttributeattributes
        .get("BreathingRate");
    breathRateRetrieve.load();
    MeasurementAttribute heartRateRetrieve = (MeasurementAttributeattributes
        .get("HeartRate");
    heartRateRetrieve.load();
    ShockAttribute shockRetrieve = (ShockAttributeattributes.get("Shock");
    shockRetrieve.load();
    MeasurementAttribute heightRetrieve = (MeasurementAttributeattributes
        .get("Height");
    heightRetrieve.load();
    MeasurementAttribute weightRetrieve = (MeasurementAttributeattributes
        .get("Weight");
    weightRetrieve.load();
    MeasurementAttribute bloodPressureAttribute = (MeasurementAttributeattributes
        .get("BloodPressureDiastolic");
    bloodPressureAttribute.load();
    MeasurementAttribute bloodPressureSysAttribute = (MeasurementAttributeattributes
        .get("BloodPressureSystolic");
    bloodPressureSysAttribute.load();
  }

  private void now() {
    date = new Date();
  }

  /**
   * Saves the actual values of the attributes.
   */
  public void saveAttributes() {
    now();
    GenderAttribute genderRetrieve = (GenderAttributeattributes
        .get("Gender");
    genderRetrieve.save();
    LocAttribute locRetrieve = (LocAttributeattributes
        .get("LevelOfConsciousness");
    locRetrieve.save();
    MeasurementAttribute breathRateRetrieve = (MeasurementAttributeattributes
        .get("BreathingRate");
    breathRateRetrieve.save();
    MeasurementAttribute heartRateRetrieve = (MeasurementAttributeattributes
        .get("HeartRate");
    heartRateRetrieve.save();
    ShockAttribute shockRetrieve = (ShockAttributeattributes.get("Shock");
    shockRetrieve.save();
    MeasurementAttribute heightRetrieve = (MeasurementAttributeattributes
        .get("Height");
    heightRetrieve.save();
    MeasurementAttribute weightRetrieve = (MeasurementAttributeattributes
        .get("Weight");
    weightRetrieve.save();
    MeasurementAttribute bloodPressureAttribute = (MeasurementAttributeattributes
        .get("BloodPressureDiastolic");
    bloodPressureAttribute.save();
    MeasurementAttribute bloodPressureSysAttribute = (MeasurementAttributeattributes
        .get("BloodPressureSystolic");
    bloodPressureSysAttribute.save();
    bmiAttribute();
  }

  /**
   * Sets the diastolic blood pressure.
   
   @param pressure
   *            observed diastolic blood pressure in mm/Hg
   @see #getBloodPressureDiastolic()
   */
  public void setBloodPressureDiastolic(String pressure) {
    bloodPressureDiastolicAttribute().value(pressure);
  }

  /**
   * Sets the systolic blood pressure.
   
   @param pressure
   *            observed systolic blood pressure in mm/Hg
   @see #getBloodPressureSystolic()
   */
  public void setBloodPressureSystolic(String pressure) {
    bloodPressureSystolicAttribute().value(pressure);
  }

  /**
   * Sets the breathing rate.
   
   @param newRate
   *            observed breathing rate in breaths/min
   @see #getBreathingRate()
   */
  public void setBreathingRate(String newRate) {
    breathingRateAttribute().value(newRate);
  }

  /**
   * Sets the patient's gender.
   
   @param gender
   *            the patient's gender
   @see #getGender()
   */
  public void setGender(String gender) {
    genderAttribute().value(gender);
  }

  /**
   * Sets a new heart rate value.
   
   @param newRate
   *            observed heart rate in beats/min
   @see #getHeartRate()
   */
  public void setHeartRate(String newRate) {
    heartRateAttribute().value(newRate);
  }

  /**
   * Sets the height of the patient.
   
   @param height
   *            patient's height in inches
   @see #getHeight()
   */
  public void setHeight(String height) {
    heightAttribute().value(height);
  }

  /**
   * Sets a level of consciousness.
   
   @param loc
   *            observed level of consciousness
   @see #getLevelOfConsciousness()
   */
  public void setLevelOfConsciousness(String loc) {
    levelOfConsciousnessAttribute().value(loc);
  }

  /**
   * Sets if patient is in shock.
   
   @param isInShock
   *            true if observed the patient is in shock
   @see #getShock()
   */
  public void setShock(boolean isInShock) {
    shockAttribute().value(isInShock);
  }

  /**
   * Saves the actual patient's data and loads another.
   
   @param name
   *            the name of the patient you want to load
   @see #getSubject()
   */
  public void setSubject(String name) {
    if (subject != null)
      saveAttributes()//alten Patienten speichern
    subject = Patient.get(name)//neuen Patienten suchen
    loadAttributes()//neue Daten laden
  }

  protected void setupAttributes() {
    attributes.put("Gender"new GenderAttribute(this));
    attributes.put("LevelOfConsciousness"new LocAttribute(this));
    attributes.put("BreathingRate"new MeasurementAttribute(this,
        PhenomenonType.get("breathing rate"), Unit.get("breaths/min")));
    attributes.put("HeartRate"new MeasurementAttribute(this,
        PhenomenonType.get("heart rate"), Unit.get("beats/min")));
    attributes.put("Shock"new ShockAttribute(this));
    attributes.put("Height"new MeasurementAttribute(this, PhenomenonType
        .get("height"), Unit.get("inches")));
    attributes.put("Weight"new MeasurementAttribute(this, PhenomenonType
        .get("weight"), Unit.get("pounds")));
    attributes.put("BMI"new BMIAttribute(this, null, null));
    attributes.put("BloodPressureDiastolic"new MeasurementAttribute(this,
        PhenomenonType.get("blood pressure diastolic"), Unit
            .get("mm Hg")));
    attributes.put("BloodPressureSystolic"new MeasurementAttribute(this,
        PhenomenonType.get("blood pressure systolic"), Unit
            .get("mm Hg")));
  }

  /**
   * Sets the patient's weight.
   
   @param weight
   *            patient's weight in pounds
   @see #getWeight()
   */
  public void setWeight(String weight) {
    weightAttribute().value(weight);
  }

  private ShockAttribute shockAttribute() {
    return (ShockAttributeattributes.get("Shock");
  }

  private MeasurementAttribute weightAttribute() {
    return (MeasurementAttributeattributes.get("Weight");
  }
}